package com.derbysoft.dswitch.adapter.ihg.dswitch2.service.impl;

import com.derbysoft.dswitch.adapter.ihg.common.domain.ChannelAuthorization;
import com.derbysoft.dswitch.adapter.ihg.common.repository.ChannelAuthorizationRepository;
import com.derbysoft.dswitch.adapter.ihg.common.utils.ErrorMessageUtils;
import com.derbysoft.dswitch.adapter.ihg.dto.OTAHotelAvailRS;
import com.derbysoft.dswitch.adapter.ihg.exception.ChannelNotFoundException;
import com.derbysoft.dswitch.adapter.ihg.exception.InvokeProviderSideException;
import com.derbysoft.remote.dswitch.core.ErrorDTO;
import com.derbysoft.remote.dswitch.core.ErrorsDTO;
import com.derbysoft.remote.dswitch.core.GenericRS;
import com.derbysoft.remote.dswitch.core.ResponseHeader;
import com.derbysoft.remote.dswitch.hotel.dto.HotelReservationRS;
import com.derbysoft.remote.dswitch.hotel.dto.ReservationRoomStayDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

public abstract class BaseHotelWebService {

    public static final String SYSTEM = "System";

    @Autowired
    private ChannelAuthorizationRepository channelAuthorizationRepository;

    @Value("${dswitch2.adapter}")
    protected String adapter;

    @Value("${provider}")
    protected String provider;

    protected ChannelAuthorization loadAuthorization(String channelPassport) {
        ChannelAuthorization authorization = channelAuthorizationRepository.loadByDerbyChannelCode(channelPassport);
        if (authorization == null) {
            throw new ChannelNotFoundException(channelPassport);
        }
        return authorization;
    }

    protected GenericRS<HotelReservationRS> createNoAllotmentResponse(OTAHotelAvailRS otaHotelAvailRS,
                                                                      ResponseHeader responseHeader, ReservationRoomStayDTO roomStayDTO) {
        GenericRS<HotelReservationRS> response = new GenericRS<HotelReservationRS>();
        ErrorsDTO errors = new ErrorsDTO();
        ErrorDTO errorDTO = new ErrorDTO();
        errorDTO.setSource(provider);
        if (otaHotelAvailRS.getErrors() == null) {
            errorDTO.setCode("NoRate");
            errorDTO.setMessage(String.format("No allotment for ratePlanCode[%s] roomTypeCode[%s] numberOfUnits[%d]",
                    roomStayDTO.getRatePlanCode(), roomStayDTO.getRoomTypeCode(), roomStayDTO.getNumberOfUnits()));
        } else {
            errorDTO.setCode(otaHotelAvailRS.getErrors().getError().get(0).getCode() == null ? SYSTEM : otaHotelAvailRS.getErrors().getError().get(0).getCode());
            StringBuilder message = new StringBuilder();
            for (com.derbysoft.dswitch.adapter.ihg.dto.Error error : otaHotelAvailRS.getErrors().getError()) {
                message.append(error.getShortText()).append(" ");
            }
            errorDTO.setMessage(message.toString());
        }
        errors.getErrorList().add(errorDTO);
        response.setErrors(errors);
        response.setHeader(responseHeader);
        return response;
    }

    protected ErrorsDTO createErrorDTO(Exception ex) {
        ErrorDTO error = new ErrorDTO();
        error.setCode(SYSTEM);
        error.setSource(ex instanceof InvokeProviderSideException ? provider : adapter);
        error.setMessage(ErrorMessageUtils.buildErrorMessage(ex));
        ErrorsDTO errors = new ErrorsDTO();
        errors.getErrorList().add(error);
        return errors;
    }
}
